package com.salt.modules.sys.service;

import com.google.api.client.util.Lists;
import com.salt.common.service.CrudService;
import com.salt.common.utils.IdGen;
import com.salt.modules.sys.entity.AppChildMenu;
import com.salt.modules.sys.entity.AppMenu;
import com.salt.modules.sys.entity.Menu;
import com.salt.modules.sys.entity.User;
import com.salt.modules.sys.mapper.AppChildMenuMapper;
import com.salt.modules.sys.mapper.AppMenuMapper;
import com.salt.modules.sys.mapper.MenuMapper;
import com.salt.modules.sys.utils.MenuUtils;
import com.salt.modules.sys.utils.UserUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description 应用菜单(一级目录)Service
 * @Author salt
 * @Date 2022/1/3
 * @Version 1.0.1
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class AppMenuService extends CrudService<AppMenuMapper, AppMenu> {

    private final AppChildMenuMapper appChildMenuMapper;
    private final MenuMapper menuMapper;

    @Transactional(readOnly = false)
    public List<Menu> getList(String tenant, List<String> tenantIds) {
        AppMenu defalutAppMenu = mapper.get("1");
        List<Menu> menuList = new ArrayList<>();
        menuList.add(menuMapper.get(defalutAppMenu.getMenuId()));
        AppMenu appMenu = new AppMenu(UserUtils.getUser().getId());
        appMenu.setTenant(tenant);
        List<AppMenu> appMenus = mapper.findList(appMenu);
        List<Menu> menus = MenuUtils.getMenus(new Menu(tenant, tenantIds, "2"));
        /*for (Menu m:menus) {
            if (defalutAppMenu.getMenuId().equals(m.getId())) menuList.add(m);
        }*/
        if (appMenus != null && !appMenus.isEmpty()) {
            for (Menu m:menus) {
                for (AppMenu am:appMenus) {
                    if (m.getId().equals(am.getMenuId())) {
                        menuList.add(m);
                        break;
                    }
                }
            }
            AppChildMenu appChildMenu = new AppChildMenu(UserUtils.getUser().getId());
            appChildMenu.setTenant(tenant);
            List<AppChildMenu> appChildMenuList = appChildMenuMapper.findList(appChildMenu);
            // ************删除掉没有权限的菜单start ************
            // 注：用户的角色的调整，用户权限也会发生变化，之前下载下来的app要清理掉没有权限的数据即sys_app_menu,sys_app_child_menu
            // 删除掉没有权限的子子级菜单
            ArrayList<String> deleteAppChildMenuIds = Lists.newArrayList();
            if (appChildMenuList != null && !appChildMenuList.isEmpty()) {
                for (AppChildMenu acm:appChildMenuList) {
                    for (Menu m:menuList) {
                        if (acm.getMenuId().equals(m.getId())) {
                            deleteAppChildMenuIds.add(acm.getId());
                            break;
                        }
                    }
                }
            }
            // 删除用户所拥有的权限里面没有app menu
            ArrayList<String> deleteAppMenuIds = Lists.newArrayList();
            for (AppMenu am:appMenus) {
                boolean flag = true;
                for (Menu m:menus) {
                    if (am.getMenuId().equals(m.getId())) {
                        flag = false;
                        break;
                    }
                }
                if (flag) deleteAppMenuIds.add(am.getId());
            }
            if (!deleteAppMenuIds.isEmpty()) {
                mapper.batchDelete(deleteAppMenuIds);
                // 删除没有权限的子级及子子级菜单
                if (appChildMenuList != null && !appChildMenuList.isEmpty()) {
                    for (AppChildMenu acm:appChildMenuList) {
                        for (String parentId:deleteAppMenuIds) {
                            if (parentId.equals(acm.getParentMenuId())) {
                                deleteAppChildMenuIds.add(acm.getId());
                                break;
                            }
                        }
                    }
                }
            }
            if (!deleteAppChildMenuIds.isEmpty()) {
                appChildMenuMapper.batchDelete(deleteAppChildMenuIds);
            }
            // ************删除掉没有权限的菜单end ************
            // 删除掉没有下载的子子级菜单
            /*if (appChildMenuList != null && !appChildMenuList.isEmpty()) { // 下载了子子级菜单
                for (Menu menu:menuList) {
                    getIsDownloadMenuList(menu, appChildMenuList);
                }
            } else {  // 当没有下载子子级菜单时
                for (Menu menu:menuList) {
                    getIsDownloadMenuList(menu, appChildMenuList);
                }
            }*/
        }
        return menuList;
    }

    @Transactional(readOnly = false)
    public void batchSave(List<String> menuIds) {
        User user = UserUtils.getUser();
        List<String> menuIdList = menuIds.stream().distinct().collect(Collectors.toList());
        List<AppMenu> appMenus = mapper.findList(new AppMenu(user.getId()));
        AppMenu defalutAppMenu = mapper.get("1");
        if (appMenus != null && !appMenus.isEmpty()) {
            Iterator<String> iterator = menuIdList.iterator();
            while (iterator.hasNext()) {
                String next = iterator.next();
                if (next.equals(defalutAppMenu.getMenuId())) {
                    iterator.remove();
                } else {
                    appMenus.stream().forEach(appMenu -> {
                        if (next.equals(appMenu.getMenuId())) iterator.remove();
                    });
                }
            }
        }
        if (!menuIdList.isEmpty()) {
            List<AppMenu> appMenuList = Lists.newArrayListWithCapacity(menuIdList.size());
            AppMenu appMenu = null;
            for (String menuId:menuIdList) {
                appMenu = new AppMenu(user.getId(), menuId);
                appMenu.setId(IdGen.uuid());
                appMenu.setCreateDate(new Date());
                appMenuList.add(appMenu);
            }
            mapper.insertBatch(appMenuList);
        }

    }

    @Transactional(readOnly = false)
    public void save(AppMenu appMenu) {
        appMenu.setId(IdGen.uuid());
        appMenu.setCreateDate(new Date());
        mapper.insert(appMenu);
    }

    public AppMenu find(AppMenu appMenu) {
        return mapper.find(appMenu);
    }

    @Transactional(readOnly = false)
    public void delete(String menuId) {
        User user = UserUtils.getUser();
        AppMenu appMenu = new AppMenu(user.getId(), menuId);
        mapper.delete(appMenu);
    }

    private void getIsDownloadMenuList(Menu menuItem, List<AppChildMenu> appChildMenuList) {
        List<Menu> children = menuItem.getChildren();
        if (children != null && !children.isEmpty()) {
            for (Menu menu:children) {
                ArrayList<Menu> isDownloadMenuList = Lists.newArrayList();
                if ("1".equals(menu.getType())) {
                    for (AppChildMenu appChildMenu:appChildMenuList) {
                        if (menu.getId().equals(appChildMenu.getMenuId())) {
                            isDownloadMenuList.add(menu);
                            break;
                        }
                    }
                } else {
                    isDownloadMenuList.add(menu);
                }
                menuItem.setChildren(isDownloadMenuList);
                getIsDownloadMenuList(menu, appChildMenuList);
            }
        }
    }

    private void getIsDownloadMenuList(Menu menuItem){
        List<Menu> children = menuItem.getChildren();
        if (children != null && !children.isEmpty()) {
            for (Menu menu:children) {
                ArrayList<Menu> isDownloadMenuList = Lists.newArrayList();
                menuItem.setChildren(isDownloadMenuList);
                getIsDownloadMenuList(menu);
            }
        }
    }

}
